package cn.hg.solon.youcan.job.utils;

import java.util.Date;

import org.dromara.hutool.core.date.DateUtil;
import org.dromara.hutool.core.exception.ExceptionUtil;
import org.dromara.hutool.core.text.CharSequenceUtil;
import org.dromara.hutool.cron.task.Task;
import org.noear.solon.Solon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hg.solon.youcan.job.constant.JobExecuteStatus;
import cn.hg.solon.youcan.job.entity.Job;
import cn.hg.solon.youcan.job.entity.JobLog;
import cn.hg.solon.youcan.job.service.JobLogService;

/**
 * 抽象quartz调用
 *
 * @author ruoyi
 */
public abstract class AbstractCronJob implements Task {
    protected Date startTime;
    protected Date createTime;

    protected Logger log = LoggerFactory.getLogger(this.getClass());

    private Job job;

    public AbstractCronJob(Job job) {
        this.job = job;
        this.createTime = DateUtil.now();
    }

    /**
     * 执行后
     *
     * @param result 工作执行上下文对象
     * @throws Throwable 异常
     */
    protected void after(Object result, Throwable e) {
        if (this.job.getIsLog()) {
            final JobLog sysJobLog = new JobLog();
            sysJobLog.setName(this.job.getName());
            sysJobLog.setGroup(this.job.getGroup());
            sysJobLog.setTarget(this.job.getTarget());
            sysJobLog.setCreatedDatetime(this.createTime);
            sysJobLog.setStartedDatetime(this.startTime);
            sysJobLog.setEndedDatetime(DateUtil.now());
            sysJobLog.setCost(sysJobLog.getEndedDatetime().getTime() - sysJobLog.getStartedDatetime().getTime());
            sysJobLog.setMessage(sysJobLog.getName() + "，耗时：" + sysJobLog.getCost() + "毫秒");
            if (e != null) {
                sysJobLog.setStatus(JobExecuteStatus.FAIL.name());
                String errorMsg = CharSequenceUtil.sub(ExceptionUtil.stacktraceToString(e) , 0, 2000);
                sysJobLog.setException(errorMsg);
                sysJobLog.setMessage(sysJobLog.getMessage() + "，异常：" + e.getMessage());
            } else {
                sysJobLog.setStatus(JobExecuteStatus.SUCCESS.name());
            }

            this.startTime = null;

            // 写入数据库当中
            Solon.context().getBean(JobLogService.class).insert(sysJobLog);
        }
    }

    /**
     * 执行前
     *
     */
    protected void before() {
        this.startTime = DateUtil.now();
    }

    /**
     * 执行方法，由子类重载
     *
     * @return 返回对象
     * @throws Exception 执行过程中的异常
     */
    protected abstract Object doExecute() throws Throwable;

    @Override
    public void execute() {
        Object result = null;
        try {
            this.before();
            result = this.doExecute();
            this.after(result, null);
        } catch (Throwable e) {
            this.log.error("任务执行异常  - ：", e);
            this.after(result, e);
        }
    }

    public Job getJob() {
        return this.job;
    }
}
